package com.tcfvic.client.panels.widgets;

import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextArea;
import com.google.gwt.user.client.ui.TextBox;
import com.tcfvic.client.PersonService;
import com.tcfvic.client.PersonServiceAsync;
import com.tcfvic.client.panels.widgets.addons.advancedtable.AdvancedTable;
import com.tcfvic.client.panels.widgets.addons.advancedtable.RowSelectionListener;
import com.tcfvic.client.pojos.Course;
import com.tcfvic.client.pojos.Courselevel;
import com.tcfvic.client.pojos.Industry;
import com.tcfvic.client.tools.CourseCategory;
import com.tcfvic.client.tools.CourseType;
import com.tcfvic.client.tools.FullTimePartTime;
import com.tcfvic.client.tools.Tools;

public class TrainingDetailsInputWidget extends FlexTable implements
		RowSelectionListener {
	private TextBox trainingId = new TextBox();
	private TextBox trainingNameTB = new TextBox();
	private TextBox costTB = new TextBox();
	private ListBox courseTypeLB = new ListBox();
	private ListBox courseIndustryLB = new ListBox();
	private ListBox courseCategoryLB = new ListBox();
	private ListBox levelLB = new ListBox();
	private TextBox lengthTB = new TextBox();
	private ListBox ftptLB = new ListBox();
	private TextBox hoursTB = new TextBox();
	private TrainingListWidget list = null;
	// private ListBox rtoLB = new ListBox();
	private TextArea notes = new TextArea();

	/**
	 * Create a remote service proxy to talk to the server-side CompanyDetails
	 * service.
	 */
	private final PersonServiceAsync personService = GWT
			.create(PersonService.class);

	public TrainingDetailsInputWidget() {
		super();

		// Create a table to layout the form options
		setCellSpacing(4);
		setWidth("100%");
		FlexCellFormatter cellFormatter = getFlexCellFormatter();

		// Add a title to the form
		setHTML(0, 0, "Add/Edit training");
		cellFormatter.setColSpan(0, 0, 4);
		cellFormatter.setHorizontalAlignment(0, 0,
				HasHorizontalAlignment.ALIGN_CENTER);

		// Add some standard form options
		int rowNum = 1;
		setHTML(rowNum, 0, "Course name");
		setWidget(rowNum, 1, trainingNameTB);
		setHTML(rowNum, 2, "Training cost");
		setWidget(rowNum++, 3, costTB);

		populateCourseType();
		setHTML(rowNum, 0, "Type");
		setWidget(rowNum, 1, courseTypeLB);

		setHTML(rowNum, 2, "Full time/Part time");
		populateFTPTList();
		setWidget(rowNum++, 3, ftptLB);

		courseIndustryLB = getIndustryList();
		setHTML(rowNum, 0, "Industry");
		setWidget(rowNum, 1, courseIndustryLB);

		// populateCourseCategory();
		// setHTML(rowNum, 0, "Category");
		// setWidget(rowNum, 1, courseCategoryLB);
		//
		// // setup level
		// final TextBox levelNameToCreate = new TextBox();
		// final DialogBox dialogBox =
		// createDialogBoxForAddLevel(levelNameToCreate);
		// // Create a button to show the dialog Box
		// Button openButton = new Button("Add new", new ClickHandler() {
		// public void onClick(ClickEvent sender) {
		// levelNameToCreate.setText("");
		// dialogBox.center();
		// dialogBox.show();
		// }
		// });
		// updateLevelCacheFromDatabase();
		// HorizontalPanel hp = new HorizontalPanel();
		// hp.add(levelLB);
		// hp.add(openButton);
		// setHTML(rowNum, 2, "Level");
		// setWidget(rowNum++, 3, hp);

		setHTML(rowNum, 2, "Length");
		setWidget(rowNum++, 3, lengthTB);

		// populateRTOs();
		// setHTML(rowNum, 2, "RTO");
		// setWidget(rowNum++, 3, rtoLB);

		setHTML(rowNum, 0, "Hours per week");
		setWidget(rowNum++, 1, hoursTB);

		notes.setVisibleLines(5);
		setHTML(rowNum, 0, "Notes");
		setWidget(rowNum++, 1, notes);

		final Button saveButton = new Button("Save");
		saveButton.getElement().setId("saveButton");
		setWidget(rowNum, 4, saveButton);

		// Add a handler to close the DialogBox
		saveButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				saveTrainingDetails();
			}
		});

		clearAllFields();
	}

	private ListBox getIndustryList() {
		final ListBox lb = new ListBox();
		personService.getAllIndustries(new AsyncCallback<List<Industry>>() {
			@Override
			public void onSuccess(List<Industry> result) {
				lb.addItem("", "");
				for (Industry industry : result) {
					lb.addItem(industry.getName(), String.valueOf(industry
							.getId()));
				}
			}

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub

			}
		});
		return lb;
	}


	// /**
	// * Create the dialog box for this example.
	// *
	// * @return the new dialog box
	// */
	// private DialogBox createDialogBoxForAddLevel(final TextBox
	// levelNameToCreate) {
	// // Create a dialog box and set the caption text
	// final DialogBox dialogBox = new DialogBox();
	// dialogBox.ensureDebugId("cwDialogBox");
	// dialogBox.setText("Create Level/Course");
	//
	// // Create a table to layout the content
	// VerticalPanel dialogContents = new VerticalPanel();
	// dialogContents.setSpacing(4);
	// dialogBox.setWidget(dialogContents);
	//
	// // Add some text to the top of the dialog
	// HTML details = new HTML(
	// "This box is to create for eg. \"Intermedia/Excel\"");
	// dialogContents.add(details);
	// dialogContents.setCellHorizontalAlignment(details,
	// HasHorizontalAlignment.ALIGN_CENTER);
	//
	// HorizontalPanel hp = new HorizontalPanel();
	// details = new HTML("Enter level/course name:");
	// hp.add(details);
	// hp.add(levelNameToCreate);
	// dialogContents.add(hp);
	// dialogContents.setCellHorizontalAlignment(details,
	// HasHorizontalAlignment.ALIGN_CENTER);
	//
	// // BUTTONS
	// hp = new HorizontalPanel();
	// // Add a save button at the bottom of the dialog
	// Button saveButton = new Button("Save", new ClickHandler() {
	// public void onClick(ClickEvent event) {
	// if (levelNameToCreate.getText() == null
	// || levelNameToCreate.getText().trim().length() == 0) {
	// new SimpleMessagePopup(
	// "Please enter level info before trying to save",
	// null).showPopup();
	// } else {
	// saveLevelToDatabaseAndRefresh(levelNameToCreate.getValue());
	// }
	// dialogBox.hide();
	// }
	// });
	// hp.add(saveButton);
	// // Add a close button at the bottom of the dialog
	// Button closeButton = new Button("Cancel", new ClickHandler() {
	// public void onClick(ClickEvent event) {
	// dialogBox.hide();
	// }
	// });
	// hp.add(closeButton);
	// dialogContents.add(hp);
	// dialogContents.setCellHorizontalAlignment(hp,
	// HasHorizontalAlignment.ALIGN_RIGHT);
	//
	// if (LocaleInfo.getCurrentLocale().isRTL()) {
	// dialogContents.setCellHorizontalAlignment(closeButton,
	// HasHorizontalAlignment.ALIGN_LEFT);
	//
	// } else {
	// dialogContents.setCellHorizontalAlignment(closeButton,
	// HasHorizontalAlignment.ALIGN_RIGHT);
	// }
	//
	// // Return the dialog box
	// return dialogBox;
	// }
	//
	// private void saveLevelToDatabaseAndRefresh(String level) {
	// Courselevel cl = new Courselevel();
	// cl.setLevel(level);
	// personService.saveCourseLevel(cl, new AsyncCallback<Void>() {
	// @Override
	// public void onSuccess(Void result) {
	// updateLevelCacheFromDatabase();
	// }
	//
	// @Override
	// public void onFailure(Throwable caught) {
	// GWT.log("Error adding course level to database", caught);
	// }
	// });
	//
	// }
	//
	// private void updateLevelCacheFromDatabase() {
	// personService
	// .getAllCourseLevels(new AsyncCallback<List<Courselevel>>() {
	//
	// @Override
	// public void onSuccess(List<Courselevel> result) {
	// populateLevels(result);
	//
	// }
	//
	// @Override
	// public void onFailure(Throwable caught) {
	// // TODO Auto-generated method stub
	//
	// }
	// });
	// }

	// private void populateRTOs() {
	// rtoLB.addItem("");
	// personService.getAllRTOs(new AsyncCallback<List<Rto>>() {
	// @Override
	// public void onSuccess(List<Rto> result) {
	// for (Rto rto : result) {
	// rtoLB.addItem(rto.getName(), String.valueOf(rto.getId()));
	// }
	// }
	//
	// @Override
	// public void onFailure(Throwable caught) {
	// GWT.log("Error retreiving RTO list", caught);
	// new SimpleMessagePopup(
	// "RTO list not retrieved due to internal error", null)
	// .showPopup();
	// }
	// });
	// }

	// private void populateLevels(List<Courselevel> result) {
	// levelLB.clear();
	// levelLB.addItem("");
	// for (Courselevel cl : result) {
	// levelLB.addItem(cl.getLevel(), String.valueOf(cl.getId()));
	// }
	// }

	// private void populateCourseCategory() {
	// courseCategoryLB.addItem("");
	// for (CourseCategory courseCategory : CourseCategory.values()) {
	// courseCategoryLB.addItem(courseCategory.getType(), courseCategory
	// .toString());
	// }
	// }

	private void populateCourseType() {
		courseTypeLB.addItem("");
		for (CourseType courseType : CourseType.values()) {
			courseTypeLB.addItem(courseType.getType(), courseType.toString());
		}
	}

	private void populateFTPTList() {
		ftptLB.addItem("");
		for (FullTimePartTime ftpt : FullTimePartTime.values()) {
			ftptLB.addItem(ftpt.getDescription(), ftpt.toString());
		}
	}

	public void addTrainingDetailsList(TrainingListWidget list) {
		this.list = list;
	}

	private boolean validInput() {
		if (trainingId.getText() != null
				&& trainingId.getText().trim().equals("-1")) {
			Integer.parseInt(trainingId.getText());
			new SimpleMessagePopup(
					"Please select a training course before trying to edit details",
					null).showPopup();
			return false;
		}
		try {
			if (costTB.getText() != null
					&& costTB.getText().trim().length() > 0) {
				Double.parseDouble(costTB.getText());
			}
		} catch (Exception e) {
			new SimpleMessagePopup(
					"The amount you supplied in the text box isn't a valid number",
					costTB).showPopup();
			return false;
		}
		return true;
	}

	private boolean minimumInput() {
		if (trainingNameTB.getText() == null
				|| trainingNameTB.getText().trim().length() == 0) {
			new SimpleMessagePopup("Please enter a training course name",
					trainingNameTB).showPopup();
			return false;
		}
		return true;
	}

	public void createNewRecord() {
		clearAllFields();
		trainingId.setText("");
	}

	public void clearAllFields() {
		trainingId.setText("-1");
		trainingNameTB.setText("");
		costTB.setText("");
		courseTypeLB.setSelectedIndex(0);
		courseIndustryLB.setSelectedIndex(0);
		courseCategoryLB.setSelectedIndex(0);
		levelLB.setSelectedIndex(0);
		lengthTB.setText("");
		ftptLB.setSelectedIndex(0);
		hoursTB.setText("");
		// rtoLB.setSelectedIndex(0);
		notes.setText("");
	}

	@Override
	public void onRowSelected(AdvancedTable sender, String rowId) {
		clearAllFields();
		personService.getTrainingDetails(Integer.valueOf(rowId),
				new AsyncCallback<Course>() {
					@Override
					public void onSuccess(Course result) {
						trainingId.setText(String.valueOf(result.getId()));
						trainingNameTB.setText(result.getName());
						notes.setText(result.getNotes());
						try {
							costTB.setText(result.getCost().toString());
						} catch (Exception e) {
						}
						if (result.getCourseType() != null
								&& result.getCourseType().trim().length() > 0) {
							CourseType type = Tools.getCourseType(result
									.getCourseType());
							courseTypeLB.setSelectedIndex(type.getId());
						}
						if (result.getIndustry() != null
								&& result.getIndustry().trim().length() > 0) {
							courseIndustryLB.setSelectedIndex(Tools
									.getSelectedIndex(courseIndustryLB, result
											.getIndustry()));
						}
						if (result.getCategory() != null
								&& result.getCategory().trim().length() > 0) {
							CourseCategory type = CourseCategory.valueOf(result
									.getCategory());
							courseCategoryLB.setSelectedIndex(type.getId());
						}
						if (result.getCourselevel() != null) {
							try {
								levelLB
										.setSelectedIndex(getSelectedIndexFromListBox(
												levelLB, String.valueOf(result
														.getCourselevel()
														.getId())));
							} catch (Exception e) {
							}
						}
						if (result.getFulltimeparttime() != null
								&& result.getFulltimeparttime().trim().length() > 0) {
							FullTimePartTime type = FullTimePartTime
									.valueOf(result.getFulltimeparttime());
							ftptLB.setSelectedIndex(type.getId());
						}
						lengthTB.setText(result.getLength());
						if (result.getHoursperweek() != null) {
							hoursTB
									.setText(result.getHoursperweek()
											.toString());
						}
						// if (result.getRto() != null) {
						// try {
						// rtoLB
						// .setSelectedIndex(getSelectedIndexFromListBox(
						// rtoLB, String.valueOf(result
						// .getRto().getId())));
						// } catch (Exception e) {
						// }
						// }
					}

					@Override
					public void onFailure(Throwable caught) {
						System.err
								.println("Error occured returning the course details: "
										+ caught);
						new SimpleMessagePopup(
								"The course record was not retrieved due to an internal error",
								null).showPopup();
					}
				});
	}

	private int getSelectedIndexFromListBox(ListBox lb, String valueToSearchFor) {
		int id = 0;

		for (int i = 0; i < lb.getItemCount(); i++) {
			if (lb.getValue(i).equals(valueToSearchFor)) {
				return i;
			}
		}

		return id;
	}

	private void saveTrainingDetails() {
		try {
			if (!validInput() || !minimumInput()) {
				return;
			}

			Course course = new Course();
			if (trainingId != null && trainingId.getText().trim().length() > 0) {
				course.setId(new Integer(trainingId.getText()));
			}

			course.setName(trainingNameTB.getText());
			course.setNotes(notes.getText());
			try {
				course.setCost(Double.valueOf(costTB.getText()));
			} catch (Exception e) {
			}

			if (courseTypeLB.getSelectedIndex() > 0) {
				course.setCourseType(courseTypeLB.getValue(courseTypeLB
						.getSelectedIndex()));
			}
			if (courseIndustryLB.getSelectedIndex() > 0) {
				course.setIndustry(courseIndustryLB.getValue(courseIndustryLB
						.getSelectedIndex()));
			}
			if (courseCategoryLB.getSelectedIndex() > 0) {
				course.setCategory(courseCategoryLB.getValue(courseCategoryLB
						.getSelectedIndex()));
			}
			if (levelLB.getSelectedIndex() > 0) {
				try {
					course.setCourselevel(new Courselevel(Integer
							.valueOf(levelLB.getValue(levelLB
									.getSelectedIndex()))));
				} catch (Exception e) {
				}
			}
			course.setLength(lengthTB.getText());

			if (ftptLB.getSelectedIndex() > 0) {
				course.setFulltimeparttime(ftptLB.getValue(ftptLB
						.getSelectedIndex()));
			}
			try {
				course.setHoursperweek(Integer.valueOf(hoursTB.getText()));
			} catch (Exception e) {
			}

			// if (rtoLB.getSelectedIndex() > 0) {
			// try {
			// course.setRto(new Rto(Integer.valueOf(rtoLB.getValue(rtoLB
			// .getSelectedIndex()))));
			// } catch (Exception e) {
			// }
			// }

			personService.saveTrainingDetails(course,
					new AsyncCallback<Void>() {
						@Override
						public void onSuccess(Void result) {
							System.out
									.println("Successfully wrote course record to dbase");
							clearAllFields();
							if (list != null) {
								list.updateTableData();
							}
							new SimpleMessagePopup("Course saved successfully",
									null).showPopup();
						}

						@Override
						public void onFailure(Throwable caught) {
							System.err
									.println("Error occured writing course to database in "
											+ "TrainingDetailsInputWidget.saveTrainingDetails: "
											+ caught);
							new SimpleMessagePopup(
									"The data was not saved due to an internal error",
									null).showPopup();
						}
					});
		} catch (Exception e) {
			new SimpleMessagePopup(
					"An error occured saving the course details: " + e, null)
					.showPopup();
		}
	}
}
